package com.zz.spring6.aop.xmlaop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 切面类
 */

@Component
public class LogAspect {

    // 设置切入点和通知类型
    // 通知类型
    // 前置     @Before()  切入点表达式配置切入点
    //@Before(value = "execution(public int com.zz.spring6.aop.xmlaop.CalculatorImpl.*(..))")
    public void beforeMethod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("logger --> 前置通知   方法名称"+methodName+"参数"+ Arrays.toString(args));
    }
    // 返回 @AfterReturning
   // @AfterReturning(value = "execution(* com.zz.spring6.aop.xmlaop.CalculatorImpl.*(..))",returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint,Object result){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("logger --> 返回  方法名称"+methodName+"返回值"+result);
    }
    // 异常 @AfterThrowing
    //  目标方法出现异常 这个通知执行
   // @AfterThrowing(value = "execution(* com.zz.spring6.aop.xmlaop.CalculatorImpl.*(..))",throwing = "ex")
    public void afterThrowingMethod(JoinPoint joinPoint,Throwable ex){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("logger --> 异常通知  方法名称"+methodName+"异常信息"+ex);
    }


    // 后置 @After
   // @After(value = "pointcut()")
    public void afterMethod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("logger --> 后置通知  方法名称"+methodName);
    }

    // 环绕 @Around()

   // @Around( "execution(* com.zz.spring6.aop.xmlaop.CalculatorImpl.*(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        String arg = Arrays.toString(args);
        Object result = null;
        try {
            System.out.println("logger --> 环绕通知== 目标方法之前执行  ");

            // 调用目标方法
             result = joinPoint.proceed();
            System.out.println("logger --> 环绕通知== 目标方法之后执行  ");

        }catch (Throwable throwable){
            throwable.printStackTrace();
            System.out.println("logger --> 环绕通知== 目标方法出现异常执行  ");
        }finally {
            System.out.println("logger --> 环绕通知== 目标方法执行完毕  ");
        }
        return result;
    }

    // 重用切入点表达式
    @Pointcut(value = "execution(* com.zz.spring6.aop.xmlaop.CalculatorImpl.*(..))")
    public void pointcut(){

    }

}
